export interface Filter<T> {
  (t: T, chain: FilterChain<T>): Promise<void>;
}

export class FilterChain<T> {
  #filters: Filter<T>[] = [];
  #filtersItr?: IterableIterator<Filter<T>> = undefined;

  addFilters(...filters: Filter<T>[]): void {
    if (filters) {
      for (const filter of filters) {
        // TODO: 检查 filter 是否合法，需要定义什么是合法
        this.#filters.push(filter);
      }
    }
  }

  async next(t: T): Promise<void> {
    this.checkFilters();

    if (this.#filtersItr === undefined) {
      this.#filtersItr = this.#filters[Symbol.iterator]();
    }

    const result = this.#filtersItr.next() as IteratorReturnResult<Filter<T>>;
    if (!result.done) {
      const filter = result.value;
      await filter(t, this);
    }
  }

  private checkFilters(): void {
    if (this.#filters.length === 0) {
      throw new Error('No filters in ' + FilterChain.name);
    }
  }
}
